package edu.hubu.talentmanagementsystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.CaseFormat;
import edu.hubu.talentmanagementsystem.common.QnUploadUtils;
import edu.hubu.talentmanagementsystem.mapper.ResourceMapper;
import edu.hubu.talentmanagementsystem.mapper.context.MapperContext;
import edu.hubu.talentmanagementsystem.model.ext.Resource;
import edu.hubu.talentmanagementsystem.service.IResourceService;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import edu.hubu.talentmanagementsystem.common.EncodeOperation;
import edu.hubu.talentmanagementsystem.common.EncodeParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

/**
 * @author moonlan
 * date 2021/3/2 下午8:45
 */
@SuppressWarnings(value = "unused")
@Service
@Transactional(rollbackFor = Exception.class)
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements IResourceService {

    private final MapperContext context;

    private final QnUploadUtils qnUploadUtils;

    @Value("${qiniu.cdn.prefix}")
    private String prefix;

    public ResourceServiceImpl(MapperContext context,QnUploadUtils qnUploadUtils) {
        this.context = context;
        this.qnUploadUtils = qnUploadUtils;
    }

    @Override
    public boolean deleteById(Integer id) {
        return context.getResourceMapper().deleteById(id) > 0;
    }

    @Override
    @EncodeOperation
    public Optional<Resource> insert(@EncodeParam Resource record) {
        int insert = context.getResourceMapper().insert(record);
        if (insert > 0) {
            return Optional.of(context.getResourceMapper().selectById(record.primaryKeyValue()));
        }
        return Optional.empty();
    }

    @Override
    public Optional<Resource> selectById(Integer id) {
        QueryWrapper<Resource> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<Resource> lambdaQueryWrapper = getColumnWrapper(wrapper.lambda()).eq(Resource::getResourceId, id);
        return Optional.of(context.getResourceMapper().selectOne(lambdaQueryWrapper));
    }

    @Override
    public List<Resource> selectAll(String order) {
        QueryWrapper<Resource> wrapper = new QueryWrapper<>();
        if (!StringUtils.hasText(order)) {
            LambdaQueryWrapper<Resource> select = getColumnWrapper(wrapper.lambda());
            return context.getResourceMapper().selectList(select);
        }
        wrapper.orderByAsc(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, order));
        LambdaQueryWrapper<Resource> select = getColumnWrapper(wrapper.lambda());
        return context.getResourceMapper().selectList(select);
    }

    @Override
    public Page<Resource> selectAllPaged( Integer currentPage,
             Integer pageSize, String order) {
        QueryWrapper<Resource> wrapper = new QueryWrapper<>();
        Page<Resource> page = new Page<>(currentPage, pageSize);
        if (!StringUtils.hasText(order)) {
            LambdaQueryWrapper<Resource> select = getColumnWrapper(wrapper.lambda());
            return context.getResourceMapper().selectPage(page, select);
        }
        wrapper.orderByAsc(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, order));
        LambdaQueryWrapper<Resource> select = getColumnWrapper(wrapper.lambda());
        return context.getResourceMapper().selectPage(page, select);
    }

    private LambdaQueryWrapper<Resource> getColumnWrapper(LambdaQueryWrapper<Resource> wrapper) {
        return wrapper.select(
                Resource::getResourceId
                    ,
                Resource::getResourceType
                    ,
                Resource::getResourceUrl
        );
    }

    @Override
    public Page<Resource> selectLikePaged( Integer currentPage,
             Integer pageSize, Resource record, String order) {
        Page<Resource> page = new Page<>(currentPage, pageSize);
        QueryWrapper<Resource> wrapper = new QueryWrapper<>();
        if (!StringUtils.hasText(order)) {
            return context.getResourceMapper().selectPage(page, getColumnWrapper(getQueryWrapper(wrapper, record)));
        }
        wrapper.orderByAsc(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, order));
        return context.getResourceMapper().selectPage(page, getColumnWrapper(getQueryWrapper(wrapper, record)));
    }

    private LambdaQueryWrapper<Resource> getQueryWrapper(QueryWrapper<Resource>wrapper, Resource record) {
        LambdaQueryWrapper<Resource> lambda = wrapper.lambda();
        if (record.getResourceId() != null) {
            lambda = lambda.eq(Resource::getResourceId,record.getResourceId());
        }
        if (record.getResourceType() != null) {
            lambda = lambda.eq(Resource::getResourceType,record.getResourceType());
        }
        if (record.getResourceUrl() != null) {
            lambda = lambda.like(Resource::getResourceUrl,record.getResourceUrl ());
        }
        return lambda;
    }

    public int count(Resource record) {
        return context.getResourceMapper().selectCount(getQueryWrapper(new QueryWrapper<>(), record));
    }

    @Override
    @EncodeOperation
    public Optional<Resource> updateById(Integer id, @EncodeParam Resource record) {
        record.setResourceId(id);
        int update = context.getResourceMapper().updateById(record);
        if (update > 0) {
            QueryWrapper<Resource> wrapper = new QueryWrapper<>();
            LambdaQueryWrapper<Resource> lambdaQueryWrapper = getColumnWrapper(wrapper.lambda()).eq(Resource::getResourceId, id);
            return Optional.of(context.getResourceMapper().selectOne(getColumnWrapper(lambdaQueryWrapper)));
        }

        return Optional.empty();
    }

    @Override
    public Resource selectDefaultHead(String role) {
        if ("staff".equals(role)){
            return context.getResourceMapper().selectById(1);
        }else {
            return context.getResourceMapper().selectById(2);
        }
    }

    @Override
    public void testAdd(MultipartFile file) {
        String url = qnUploadUtils.upload(file);
        Resource resource = new Resource();
        resource.setResourceType(1);
        resource.setResourceUrl(url);

        context.getResourceMapper().insert(resource);
    }

    @Override
    public String testGetUrl(Integer resourceId) {
        Resource resource = context.getResourceMapper().selectById(resourceId);
        return qnUploadUtils.getPrivateUrl(resource.getResourceUrl());
    }
}
